/** @file         lzm_mlog_api.h
 *  @brief        简要说明
 *  @details      详细说明
 *  @author       lzm
 *  @date         2022-10-25 12:49:43
 *  @version      v1.0
 *  @copyright    Copyright By lizhuming, All Rights Reserved
 *
 **********************************************************
 *  @LOG 修改日志:
 **********************************************************
*/

#ifndef __LZM_MLOG_API__
#define __LZM_MLOG_API__

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#include "lzm_mlog_cfg.h"

#ifdef __cplusplus
extern "C" {
#endif

void zm_mlog_output(uint8_t level, uint8_t fmt, const char *tag, const char *file, const char *func, const long line, const char *format, ...);
extern void (*lzm_mlog_assert_hook)(const char* expr, const char* func, size_t line);

/* lzm mbed log software version number */
#define LZM_MLOG_SW_VERSION                 "0.0.1"

/* mlog's level */
enum
{
    LZM_MLOG_LVL_ASSERT,
    LZM_MLOG_LVL_ERROR,
    LZM_MLOG_LVL_WARN,
    LZM_MLOG_LVL_INFO,
    LZM_MLOG_LVL_DEBUG,
    LZM_MLOG_LVL_VERBOSE,
    LZM_MLOG_LVL_TOAL_NUM,
};

/* mlog's formats */
enum
{
    LZM_MLOG_FMT_LVL    = 0x01,
    LZM_MLOG_FMT_TAG    = 0x02,
    LZM_MLOG_FMT_TIME   = 0x04,
    LZM_MLOG_FMT_FILE   = 0x08,
    LZM_MLOG_FMT_TASK   = 0x10,
    LZM_MLOG_FMT_FUNC   = 0x20,
    LZM_MLOG_FMT_LINE   = 0x40,
};
#define LZM_MLOG_FMT_ALL    (LZM_MLOG_FMT_LVL|LZM_MLOG_FMT_TAG|LZM_MLOG_FMT_TIME|\
                            LZM_MLOG_FMT_FILE|LZM_MLOG_FMT_TASK|LZM_MLOG_FMT_FUNC|LZM_MLOG_FMT_LINE)


/* lzm mbed log: output. basic mlog func */
#ifdef LZM_MLOG_OUTPUT_ENABLE
    #define LZM_MLOG_PRINTF_TAG(level, fmt, tag, ...)   \
        do  \
        {   \
            if (LZM_MLOG_OUTPUT_LVL >= level)   \
                zm_mlog_output(level, fmt, tag, __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
        }while(0)
#else
    #define LZM_MLOG_PRINTF_TAG(level, tag, fmt, ...)
#endif

/* zm mbed log: assert */
#ifdef LZM_MLOG_ASSERT_ENABLE
    #define LZM_MLOG_ASSERT(message, assertion) \
    if (!(assertion))   \
    {   \
        if (lzm_mlog_assert_hook == NULL) { \
            LZM_MLOG_PRINTF_TAG(LZM_MLOG_LVL_ASSERT, LZM_MLOG_FMT_ALL, "lzm_mlog", "(%s) has assert failed at %s:%ld.", #assertion, __FUNCTION__, __LINE__);    \
            while (1);  \
        } else {    \
            lzm_mlog_assert_hook(#assertion, __FUNCTION__, __LINE__);   \
        }   \
    }
#else
    #define LZM_MLOG_ASSERT(message, assertion)
#endif

#endif /* Head define end*/
